import { SelectQueryBuilder } from 'typeorm';
import { PaginationDto, PaginationResult, SearchDto } from '../dto/pagination.dto';

export class PaginationUtil {
  /**
   * 应用分页到查询构建器
   */
  static applyPagination<T>(
    queryBuilder: SelectQueryBuilder<T>,
    paginationDto: PaginationDto
  ): SelectQueryBuilder<T> {
    const { page = 1, pageSize = 10 } = paginationDto;
    return queryBuilder
      .skip((page - 1) * pageSize)
      .take(pageSize);
  }

  /**
   * 应用搜索条件到查询构建器
   */
  static applySearchConditions<T>(
    queryBuilder: SelectQueryBuilder<T>,
    searchDto: SearchDto,
    entityAlias: string,
    keywordFields: string[] = []
  ): SelectQueryBuilder<T> {
    const { keyword, createTimeStart, createTimeEnd, sortBy, sortOrder = 'DESC' } = searchDto;

    // 关键词搜索
    if (keyword && keywordFields.length > 0) {
      const conditions = keywordFields.map(field => `${entityAlias}.${field} LIKE :keyword`).join(' OR ');
      queryBuilder.andWhere(`(${conditions})`, { keyword: `%${keyword}%` });
    }

    // 创建时间范围搜索
    if (createTimeStart) {
      queryBuilder.andWhere(`DATE(${entityAlias}.createTime) >= :createTimeStart`, { 
        createTimeStart 
      });
    }

    if (createTimeEnd) {
      queryBuilder.andWhere(`DATE(${entityAlias}.createTime) <= :createTimeEnd`, { 
        createTimeEnd 
      });
    }

    // 排序
    if (sortBy) {
      const orderDirection = sortOrder === 'ASC' ? 'ASC' : 'DESC';
      queryBuilder.orderBy(`${entityAlias}.${sortBy}`, orderDirection);
    }

    return queryBuilder;
  }

  /**
   * 执行分页查询并返回结果
   */
  static async paginate<T>(
    queryBuilder: SelectQueryBuilder<T>,
    paginationDto: PaginationDto
  ): Promise<PaginationResult<T>> {
    const { page = 1, pageSize = 10 } = paginationDto;
    
    const paginatedQuery = this.applyPagination(queryBuilder, paginationDto);
    const [list, total] = await paginatedQuery.getManyAndCount();

    return {
      list,
      total,
      page,
      pageSize,
    };
  }

  /**
   * 构建完整的搜索和分页查询
   */
  static async searchAndPaginate<T>(
    queryBuilder: SelectQueryBuilder<T>,
    searchDto: SearchDto,
    entityAlias: string,
    keywordFields: string[] = [],
    allowedSortFields: string[] = []
  ): Promise<PaginationResult<T>> {
    // 应用搜索条件
    this.applySearchConditions(queryBuilder, searchDto, entityAlias, keywordFields);

    // 验证排序字段
    if (searchDto.sortBy && allowedSortFields.length > 0) {
      const sortBy = allowedSortFields.includes(searchDto.sortBy) ? searchDto.sortBy : allowedSortFields[0];
      searchDto.sortBy = sortBy;
    }

    // 执行分页查询
    return this.paginate(queryBuilder, searchDto);
  }
}